package com.zhou.common.lib.util;

import lombok.extern.slf4j.Slf4j;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Slf4j
public class OkhttpUtils {

    private static final OkHttpClient client;

    static {
        okhttp3.OkHttpClient.Builder clientBuilder = new okhttp3.OkHttpClient.Builder()
                //读取超时
                .readTimeout(10000, TimeUnit.SECONDS)
                //连接超时
                .connectTimeout(10000, TimeUnit.SECONDS)
                //写入超时
                .writeTimeout(10000, TimeUnit.SECONDS)
                //总超时时间
                .callTimeout(10000, TimeUnit.SECONDS)
                //默认是最大5个，空闲5个
//                .connectionPool(new ConnectionPool())
                .addInterceptor(new LoggingInterceptor());
        client = clientBuilder.build();
    }

    public static void main(String[] args) {
        String JsonString = "{\n" +
                "  \"policyId\": 11,\n" +
                "  \"uscc\": \"111\"\n" +
                "}";
        String url = "http://192.168.150.175:9093/portal/socialInsurance/statistic";
        Headers headers = Headers.of("Authorization", "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMTEiLCJhY2NvdW50IjoiMTExIiwiZXhwIjoxNjg2NDA0MjI5fQ.bkpiJ1ONBRt74odMTt4aRS9o7SKxFApUJjqm30vp0n4");
        postWithJsonSync(url, headers, JsonString);
    }

    public static void baseReq() {
        Request request = new Request.Builder().url("http://www.baidu.com").build();
        Response response = null;
        try {
            response = client.newCall(request).execute();
            log.info(response.body().string());
        } catch (IOException e) {
            log.error("{}", e);
        }
    }

    public static void asyncReq() {
        String url = "http://wwww.baidu.com";
        final Request request = new Request.Builder()
                .url(url)
                .get()//默认就是GET请求，可以不写
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                log.info("onFailure: ", e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                log.info("onResponse: {}", response.body().string());
            }
        });
    }

    public static void postReq() {
        MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
        String requestBody = "I am Jdqm.";
        Request request = new Request.Builder()
                .url("https://api.github.com/markdown/raw")
                .post(RequestBody.create(mediaType, requestBody))
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                log.info("onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                log.info(response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    log.info(headers.name(i) + ":" + headers.value(i));
                }
                log.info("onResponse: " + response.body().string());
            }
        });
    }

    /**
     * 异步执行
     * @param url
     * @param headers
     * @param body
     * @param callback
     */
    public static void postWithJsonAsync(String url, Headers headers, Object body, Callback callback) {
        RequestBody requestBody = null;
        if (body instanceof String) {
            requestBody =
                    RequestBody.create(MediaType.parse("application/json"), (String) body);
        } else {
            requestBody =
                    RequestBody.create(MediaType.parse("application/json"), JSONUtils.toJson(body));
        }
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .headers(headers)
                .build();
        client.newCall(request).enqueue(callback);
    }

    /**
     * 同步执行
     * @param url
     * @param headers
     * @param body
     * @return
     */
    public static String postWithJsonSync(String url, Headers headers, Object body) {
        RequestBody requestBody = null;
        if (body instanceof String) {
            requestBody =
                    RequestBody.create(MediaType.parse("application/json"), (String) body);
        } else {
            requestBody =
                    RequestBody.create(MediaType.parse("application/json"), JSONUtils.toJson(body));
        }

        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .headers(headers)
                .build();

        String res = null;
        try {
            Response response = client.newCall(request).execute();
            res = response.body().string();
        } catch (IOException e) {
            log.error("OkhttpUtils execute postWithJson fail", e);
            throw new RuntimeException(e);
        }
        return res;
    }


    public static void postReqWithForm() {
        RequestBody requestBody = new FormBody.Builder()
                .add("search", "Jurassic Park")
                .build();
        Request request = new Request.Builder()
                .url("https://en.wikipedia.org/w/index.php")
                .post(requestBody)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                log.info("onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                log.info(response.protocol() + " " + response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i = 0; i < headers.size(); i++) {
                    log.info(headers.name(i) + ":" + headers.value(i));
                }
                log.info("onResponse: " + response.body().string());
            }
        });

    }

    public static void req() {
        Request request = new Request.Builder()
                .url("http://www.publicobject.com/helloworld.txt")
                .header("User-Agent", "OkHttp Example")
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });

    }

    public static class LoggingInterceptor implements Interceptor {
        private static final String TAG = "LoggingInterceptor";

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            long startTime = System.nanoTime();
            log.info(TAG, String.format("Sending request %s on %s%n%s",
                    request.url(), chain.connection(), request.headers()));

            Response response = chain.proceed(request);

            long endTime = System.nanoTime();
            log.info(TAG, String.format("Received response for %s in %.1fms%n%s",
                    response.request().url(), (endTime - startTime) / 1e6d, response.headers()));
            return response;
        }
    }


}
